package service

import (
	"context"
	"errors"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
	"vpom_-system/global"
	"vpom_-system/model/mongoDB"
	"vpom_-system/utils"
)

type JwtService struct {
}

// 主要就是写两个缓存。
// 1.一个是登入之后记录 refresh 的缓存 id: jwt: 过期时间
// 2.另外一个就是黑名单，主要的作用就是判断这个jwt是否已经登出
// AccessToken ：id

// SetMongodbJWT 设置缓存，登入之后记录
func (jwtService *JwtService) SetMongodbJWT(jwt string, id uint) error {
	// 解析配置中的JWT过期时间
	dr, err := utils.ParseDuration(global.Config.Jwt.RefreshTokenExpireTime)
	if err != nil {
		return err
	}
	// 写一个对象
	revokedToken := mongoDB.CacheToken{
		Token:     jwt,
		ExpiresAt: time.Now().Add(dr).UTC(),
		UserID:    id,
	}

	// 构建查询条件：用户ID + Token（可选）
	filter := bson.M{"userId": id}
	update := bson.M{"$set": revokedToken}
	opts := options.Update().SetUpsert(true)

	collection := global.MongoClient.Database(global.Config.Mongo.Database).Collection("revoked_tokens")
	_, err = collection.UpdateOne(context.Background(), filter, update, opts)
	return err
}

func (jwtService *JwtService) GetMongodbJWT(id uint) (string, error) {
	collection := global.MongoClient.Database(global.Config.Mongo.Database).Collection("revoked_tokens")
	// 构建查询条件：用户ID + Token（可选）
	filter := bson.M{
		"userId": id, // 必选：用户ID
	}

	var result mongoDB.CacheToken
	err := collection.FindOne(context.Background(), filter).Decode(&result)
	if err != nil {
		return result.Token, mongo.ErrNoDocuments
	}
	return result.Token, nil
}

func (jwtService *JwtService) JoinInBlacklist(jwt string) error {
	collection := global.MongoClient.Database(global.Config.Mongo.Database).Collection("token_blacklist")
	collection2 := global.MongoClient.Database(global.Config.Mongo.Database).Collection("revoked_tokens")
	// 构建查询条件：用户ID + Token（可选）
	filter := bson.M{
		"token": jwt,
	}
	//获取jwt过期时间
	var result mongoDB.CacheToken
	err := collection2.FindOne(context.Background(), filter).Decode(&result)
	if err != nil {
		return err
	}
	//
	TokenBlack := mongoDB.TokenBlack{
		Token:     jwt,
		ExpiresAt: result.ExpiresAt,
	}
	_, err = collection.InsertOne(context.Background(), TokenBlack)
	return nil
}

// IsInBlacklist 判断这个是不是在黑名单中
func (jwtService *JwtService) IsInBlacklist(jwt string) bool {
	collection := global.MongoClient.Database(global.Config.Mongo.Database).Collection("token_blacklist")
	// 构建查询条件：用户ID + Token（可选）
	filter := bson.M{
		"token": jwt, // 必选：用户ID
	}

	var result mongoDB.CacheToken
	err := collection.FindOne(context.Background(), filter).Decode(&result)

	if errors.Is(err, mongo.ErrNoDocuments) {
		return false // 未找到记录
	}
	if err != nil {
		return false
	}
	return true
}

// GetAllRevokedJWTs 获取用户所有被注销的JWT列表
func GetAllRevokedJWTs(collection *mongo.Collection, userID uint) ([]string, error) {
	filter := bson.M{"userId": userID}

	cursor, err := collection.Find(context.Background(), filter)
	if err != nil {
		return nil, err
	}
	defer cursor.Close(context.Background())

	var tokens []string
	for cursor.Next(context.Background()) {
		var doc mongoDB.CacheToken
		if err := cursor.Decode(&doc); err != nil {
			return nil, err
		}
		tokens = append(tokens, doc.Token)
	}
	return tokens, nil
}
